using Ruitu.Edu.TrainingDemo.Models;
using Microsoft.Extensions.Options;
using OrchardCore.Settings;

namespace Ruitu.Edu.TrainingDemo.Services;

/// <summary>
/// 演示设置配置类 - 从站点设置加载选项
/// 
/// 主要用途：
/// - 演示如何从站点设置加载配置选项
/// - 展示 ASP.NET Core 选项模式的使用
/// - 支持多种配置源（站点设置、appsettings.json）
/// 
/// 使用场景：
/// - 需要从站点设置读取配置
/// - 需要支持多种配置源
/// - 需要动态配置管理
/// 
/// 设计原因：
/// - 利用 ASP.NET Core 的选项模式
/// - 支持 Orchard Core 的站点设置
/// - 提供灵活的配置管理
/// 
/// 设计模式：
/// - 配置模式：实现 IConfigureOptions 接口
/// - 依赖注入模式：通过构造函数注入服务
/// - 选项模式：使用 ASP.NET Core 选项模式
/// </summary>
public class DemoSettingsConfiguration : IConfigureOptions<DemoSettings>
{
    private readonly ISiteService _siteService;

    /// <summary>
    /// 初始化演示设置配置的新实例
    /// </summary>
    /// <param name="siteService">站点服务</param>
    public DemoSettingsConfiguration(ISiteService siteService) => _siteService = siteService;

    /// <summary>
    /// 配置演示设置选项
    /// </summary>
    /// <param name="options">要配置的选项</param>
    public void Configure(DemoSettings options)
    {
        // 方法参数来自其他配置选项，例如如果设置了 appsettings.json 文件，或者将为 null。
        // 您可以决定如果同时设置了两个设置应该发生什么。这里如果设置了另一个，我们将使用它。
        if (!string.IsNullOrEmpty(options.Message)) return;

        // 如果您想尝试这个，请在您的 Web 应用程序的 appsettings.json 文件中添加一个 "OrchardCore" 部分。
        // 所以最终它应该看起来像这样：
        ////{
        ////  "Logging": {
        ////    "IncludeScopes": false,
        ////    "LogLevel": {
        ////      "Default": "Warning"
        ////    }
        ////  },
        ////  "OrchardCore": {
        ////    "Lombiq_TrainingDemo": {
        ////      "Message": "This comes from appsettings!"
        ////    }
        ////  }
        ////}

        // 注意，要使此工作，需要从 Startup 类访问 IShellConfiguration，所以快速查看
        // 我们在那里有什么与设置相关的内容，然后回来！

        // 不幸的是，这里没有异步，所以我们需要同步运行这个。
        var settings = _siteService.GetSettingsAsync<DemoSettings>().GetAwaiter().GetResult();

        options.Message = settings.Message;
    }
}
